package com.liu.mybatisPlus.poke.service.impl;

import com.liu.mybatisPlus.poke.entity.base.PokeSkill;
import com.liu.mybatisPlus.poke.service.PokeSkillService;
import com.liu.mybatisPlus.poke.service.SyncPokeSkillService;
import com.liu.qqRobot.poke.callable.SyncPokeSkillCallable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SyncPokeSkillServiceImpl implements SyncPokeSkillService {

    @Resource
    private PokeSkillService pokeSkillService;

    @Override
    public void syncPokeSkill() throws IOException, InterruptedException {
        List<String> regionList = Arrays.asList("关都", "城都", "丰缘", "神奥", "合众", "卡洛斯", "阿罗拉", "伽勒尔", "帕底亚");
        String url = "https://wiki.52poke.com/zh-hans/%E6%8B%9B%E5%BC%8F%E5%88%97%E8%A1%A8";
        Connection connect = Jsoup.connect(url);
        Element body = connect.get().body();
        // 创建多线程
        CountDownLatch countDownLatch = new CountDownLatch(regionList.size());
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor((int) countDownLatch.getCount(),
                (int) countDownLatch.getCount() + 1, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        List<PokeSkill> existPokeSkillList = pokeSkillService.list();
        Map<Integer, PokeSkill> existPokeSkillMap = existPokeSkillList.stream().collect(Collectors.toMap(PokeSkill::getWikiId, p -> p));
        List<PokeSkill> pokeSkillList = new ArrayList<>();
        List<Future<List<PokeSkill>>> threadResult = new ArrayList<>();
        regionList.forEach(region -> {
            threadResult.add(threadPoolExecutor.submit(new SyncPokeSkillCallable(body, region, countDownLatch, existPokeSkillMap)));
        });
        countDownLatch.await();
        threadResult.forEach(thread -> {
            try {
                pokeSkillList.addAll(thread.get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        });
        List<PokeSkill> insertList = pokeSkillList.stream().filter(p -> p.getId() == null).collect(Collectors.toList());
        pokeSkillService.saveBatch(insertList);
        List<PokeSkill> updateList = pokeSkillList.stream().filter(p -> p.getId() != null).collect(Collectors.toList());
        pokeSkillService.updateBatchById(updateList);
    }

}
